// PolygonRenderer.java
// by Alexandre Martins, 2013
// MAC 5857 - Prof. Leonidas

package example.ilm.gui;

import example.ilm.model.Workspace;
import example.ilm.model.GeometricElement;
import example.ilm.model.Polygon;
import java.util.List;
import java.util.Iterator;
import java.awt.geom.Point2D;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Shape;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.lang.Math;

public class PolygonRenderer implements GeometricElementRenderer
{
    private Polygon polygon;

    public PolygonRenderer(Polygon pol)
    {
        polygon = pol;
    }

    public GeometricElement getGeometricElement()
    {
        return polygon;
    }

    public void render(Graphics2D g)
    {
        // spawn the shape that will be drawn
        Shape shape = new Polygon2D();
        Iterator it = polygon.getTransformedVertices().iterator();
        while(it.hasNext()) {
            Point2D q = (Point2D)(it.next());
            ((Polygon2D)shape).addPoint((float)q.getX(), (float)q.getY());
        }

        // render it
        g.setStroke(new BasicStroke(1.0f));
        g.setPaint(polygon.getColor());
        g.fill(shape);
        g.setPaint(Color.black);
        g.draw(shape);
    }

    public void renderTranslucent(Graphics2D g)
    {
        // spawn the shape that will be drawn
        Shape shape = new Polygon2D();
        Iterator it = polygon.getTransformedVertices().iterator();
        while(it.hasNext()) {
            Point2D q = (Point2D)(it.next());
            ((Polygon2D)shape).addPoint((float)q.getX(), (float)q.getY());
        }

        // render it
        g.setStroke(new BasicStroke(1.0f));
        g.setPaint(polygon.getColor());
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f));
        g.fill(shape);
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
        g.setPaint(Color.black);
        g.draw(shape);
    }

    public void renderVertices(Graphics2D g)
    {
        final int VERTEX_SIZE = Workspace.VERTEX_SIZE;
        final int ROTATIONPOINT_DISTANCE = Workspace.ROTATIONPOINT_DISTANCE;

        // get a few points
        Point2D first = null, second = null, last = null;
        Iterator it = polygon.getTransformedVertices().iterator();
        for(int j = 0; it.hasNext(); j++) {
            Point2D p = (Point2D)(it.next());
            if(j == 0)
                first = p;
            else if(j == 1)
                second = p;
            else
                last = p;
        }

        // rotation
        if(first != null && second != null && last != null) {
            Point2D midpoint = new Point2D.Double(0.5 * (second.getX() + last.getX()), 0.5 * (second.getY() + last.getY()));
            double directionX = first.getX() - midpoint.getX(), directionY = first.getY() - midpoint.getY();
            double norm = Math.sqrt(directionX * directionX + directionY * directionY);
            if(norm > 1e-5) {
                directionX /= norm; directionY /= norm;
                Point2D rotpoint = new Point2D.Double(first.getX() + directionX * ROTATIONPOINT_DISTANCE, first.getY() + directionY * ROTATIONPOINT_DISTANCE);
                rotpoint.setLocation(rotpoint.getX() - VERTEX_SIZE/2, rotpoint.getY() - VERTEX_SIZE/2);

                g.setPaint(Color.gray);
                g.drawLine((int)first.getX(), (int)first.getY(), (int)rotpoint.getX() + VERTEX_SIZE/2, (int)rotpoint.getY() + VERTEX_SIZE/2);

                g.setPaint(polygon.getHighlightedVertex() != polygon.getNumberOfVertices() ? Color.green : Color.pink);
                g.fillOval((int)rotpoint.getX(), (int)rotpoint.getY(), VERTEX_SIZE, VERTEX_SIZE);
                g.setPaint(Color.black);
                g.drawOval((int)rotpoint.getX(), (int)rotpoint.getY(), VERTEX_SIZE, VERTEX_SIZE);
            }
        }

        // scale
        it = polygon.getTransformedVertices().iterator();
        for(int myId = 0; it.hasNext(); myId++) {
            Point2D p = (Point2D)(it.next());
            p.setLocation(p.getX() - VERTEX_SIZE/2, p.getY() - VERTEX_SIZE/2);

            g.setPaint(polygon.getHighlightedVertex() != myId ? Color.lightGray : Color.pink);
            g.fillRect((int)p.getX(), (int)p.getY(), VERTEX_SIZE, VERTEX_SIZE);
            g.setPaint(Color.black);
            g.drawRect((int)p.getX(), (int)p.getY(), VERTEX_SIZE, VERTEX_SIZE);
        }
    }
}
